package com;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.HashMap;
import java.util.Map;

public class TestWeek {
	
	public static void main(String[] args) {

        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime sourceTime = LocalDateTime.parse("2020-02-03 17:07:05", df);
        Map<String, Object> weekNoOfMonth = getMonthNoAndWeekNo(sourceTime);
        System.out.println("weekNoOfMonth :" + weekNoOfMonth);

        LocalDateTime sourceTime2 = LocalDateTime.parse("2020-02-16 17:07:05", df);
        Map<String, Object> weekNoOfMonth2 = getMonthNoAndWeekNo(sourceTime2);
        System.out.println("weekNoOfMonth2 :" + weekNoOfMonth2);

        LocalDateTime sourceTime3 = LocalDateTime.parse("2020-12-31 17:07:05", df);
        Map<String, Object> weekNoOfMonth3 = getMonthNoAndWeekNo(sourceTime3);
        System.out.println("weekNoOfMonth3 :" + weekNoOfMonth3);

    }

	/**
     * 获取几月份的第几周 [X月份第X周]
     *
     * @param sourceTime 这个推荐取00:00:00时间
     * @return
     */
    public static Map<String, Object> getMonthNoAndWeekNo(LocalDateTime sourceTime) {
        Map<String, Object> map = new HashMap<>();
        String monthNoAndWeekNo = null;
        //获取当月的第一天
        LocalDateTime firstDayOfMonth = getFirstLocalDayOfMonth(sourceTime);

        //获取月第一天开始的周一,从当月第一天开始找
        LocalDateTime firstMondayOfMonth = firstDayOfMonth;
        for (int i = 0; i < 6; i++) {
            DayOfWeek dayOfWeekTemp = firstMondayOfMonth.getDayOfWeek();
            if (dayOfWeekTemp.equals(DayOfWeek.MONDAY)) {
                break;
            }
            //往后推一天
            firstMondayOfMonth = firstMondayOfMonth.plusDays(1);
        }

        //比较当月的第一个星期一 < = 参数时间
        if (!firstMondayOfMonth.isBefore(sourceTime)) {
            //如果当月的第一个周一大于参数时间,则要计算到上个月份去
            //获取上一个月的第一个周一
            LocalDateTime lastMontLocalDateTime = sourceTime.minusMonths(1);
            //上个月的第一天
            LocalDateTime firstDayOfMonth_last = getFirstLocalDayOfMonth(lastMontLocalDateTime);
            //从上个月的第一天开始找周一
            LocalDateTime firstMondayOfMonth_last = firstDayOfMonth_last;
            for (int i = 0; i < 6; i++) {
                DayOfWeek dayOfWeekTemp = firstMondayOfMonth_last.getDayOfWeek();
                if (dayOfWeekTemp.equals(DayOfWeek.MONDAY)) {
                    break;
                }
                //往后推一天
                firstMondayOfMonth_last = firstMondayOfMonth_last.plusDays(1);
            }

            //  计算两个时间间隔天数 (上月第一个周一 减去 当前时间)
            Duration duration = Duration.between(firstMondayOfMonth_last, sourceTime);
            long diffDays = duration.toDays(); //相差的天数
            //第几周weekNo
            long weekNo = (diffDays / 7) + 1;
            //月份
            int monthNo = firstMondayOfMonth_last.getMonth().getValue();//汉字版月份
            String monthChinese = getMonthChinese(monthNo);
            monthNoAndWeekNo = monthChinese + "月份" + "第" + weekNo + "周";
            map.put("monthNo", monthNo);
            map.put("weekNo", weekNo);
            map.put("monthNoAndWeekNo", monthNoAndWeekNo);

        } else {
            //当月第一个周一在当前时间之前 firstMondayOfMonth<=sourceTime
            //计算两个时间间隔天数
            int dayOfMonthFirstMonday = firstMondayOfMonth.getDayOfMonth();
            int dayOfMonthSourceTime = sourceTime.getDayOfMonth();

            int diffDays = dayOfMonthSourceTime - dayOfMonthFirstMonday;
            //第几周weekNo
            int weekNo = (diffDays / 7) + 1;
            //月份
            int monthNo = sourceTime.getMonth().getValue();

            map.put("monthNo", monthNo);
            map.put("weekNo", weekNo);
            //汉字版月份
            String monthChinese = getMonthChinese(monthNo);
            monthNoAndWeekNo = monthChinese + "月份" + "第" + weekNo + "周";
            map.put("monthNoAndWeekNo", monthNoAndWeekNo);
        }

        return map;
    }
	/**
     * java8(经测试别的版本获取2月有bug) 获取某月第一天的00:00:00
     *
     * @return
     */
    public static LocalDateTime getFirstLocalDayOfMonth(LocalDateTime localDateTime) {
        return localDateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
    }
    /**
     * 获取汉字版月份
     *
     * @param monthNo 第几月
     * @return
     */
    public static String getMonthChinese(int monthNo) {
        switch (monthNo) {
            case 1:
                return "一";
            case 2:
                return "二";
            case 3:
                return "三";
            case 4:
                return "四";
            case 5:
                return "五";
            case 6:
                return "六";
            case 7:
                return "七";
            case 8:
                return "八";
            case 9:
                return "九";
            case 10:
                return "十";
            case 11:
                return "十一";
            case 12:
                return "十二";
            default:
                break;
        }
        return null;
    }
}
